package org.aldar.bquest.logic;

import org.aldar.bquest.constants.IConstants;
import org.aldar.bquest.logic.controller.level.LevelDef;
import org.aldar.bquest.logic.controller.level.LevelDefinition;
import org.aldar.bquest.profile.GameProfile;
import org.aldar.bquest.resources.ResourceManager;
import org.aldar.bquest.resources.Texts;
import org.aldar.bquest.screens.MainBoardScreen;
import org.aldar.bquest.sound.GameSound;
import org.aldar.bquest.util.CustomButtonSprite;
import org.aldar.bquest.util.Logger;
import org.aldar.bquest.util.SQLiteHelper;
import org.andengine.entity.Entity;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.text.Text;
import org.andengine.entity.text.TextOptions;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.util.adt.align.HorizontalAlign;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static org.aldar.bquest.util.SpriteUtil.revealEntityAndChildren;

/**
 * User: Daria
 * Date: 7/16/14 11:49 AM
 */
public class GameTutorial implements IConstants {

    private CustomButtonSprite buttonNext;
    private CustomButtonSprite buttonPrev;
    private CustomButtonSprite buttonClose;
    private final List<TutorialPage> tutorialPages = new LinkedList<TutorialPage>();
    private int currentPageIndex = 0;

    public enum TutorialSection {
        TUTORIAL_MAIN_GOAL(Texts.TEXTS_TUTORIAL_MAIN_GOAL),
        TUTORIAL_CRYSTAL_TILE(Texts.TEXTS_TUTORIAL_CRYSTAL), //level 1
        TUTORIAL_ABILITIES_MOVEHERO_CONCERT(Texts.TEXTS_TUTORIAL_MOVE_HERO), //level 1
        TUTORIAL_ABILITIES_EXPLODE9_COLLECT(Texts.TEXTS_TUTORIAL_MOVE_HERO), //level 2
        TUTORIAL_ABILITY_TILE_MISSILE(Texts.TEXTS_TUTORIAL_MOVE_HERO); //level 3


        private Texts text;

        TutorialSection(Texts text) {
            this.text = text;
        }
    }

    private Entity getSpriteForSection(TutorialSection section) {
        ITextureRegion tutorialSection = ResourceManager.getInstance().getTutorialSectionsRegion(section, MainBoardScreen.getInstance());
        if (tutorialSection != null) {
            return new Sprite(0, 0, tutorialSection, MainBoardScreen.getScm().getVertexBufferObjectManager());
        } else {
            return new Entity();
        }
    }

    private boolean tutorialEnabled = false;

    private static final Logger LOG = new Logger(GameTutorial.class);

    private List<TutorialSection> coveredSections;

    Map<String, String> savedData = null;


    public GameTutorial(SQLiteHelper mSQLiteHelper) {
        savedData = mSQLiteHelper.queryData();
        coveredSections = new LinkedList<TutorialSection>();

        for (TutorialSection section : TutorialSection.values()) {
            if (savedData.get(section.name()) != null) {
                coveredSections.add(section);
            }
        }
    }

    public static void eraseDbState(SQLiteHelper sqLiteHelper) {
        for (TutorialSection section : TutorialSection.values()) {
            sqLiteHelper.deleteValue(section.name());
        }
    }

    private void addCoveredSection(TutorialSection section) {
        MainBoardScreen.getmSQLiteHelper().insertOrUpdateValue(section.name(), "covered");
        coveredSections.add(section);
    }


    private void showTutorial() {

        MainBoardScreen.getScm().setBgTouchAreas(false, false);

        buttonNext = new CustomButtonSprite(CAMERA_WIDTH / 2 + 40, 80,
                ResourceManager.getInstance().getButtonNextRegion().getTextureRegion(0),
                ResourceManager.getInstance().getButtonNextRegion().getTextureRegion(1),
                ResourceManager.getInstance().getButtonNextRegion().getTextureRegion(1),
                MainBoardScreen.getScm().getVertexBufferObjectManager(),
                new CustomButtonSprite.OnClickListener() {
                    @Override
                    public void onClick(CustomButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {
                        tutorialPages.get(currentPageIndex).detachPageAndShow(currentPageIndex + 1);
                        MainBoardScreen.getInstance().getGameSound().playTurnPageSound();
                        buttonPrev.setEnabled(true);
                    }
                });
        buttonNext.setPlaySound(false);
        buttonPrev = new CustomButtonSprite(CAMERA_WIDTH / 2 - 40, 80,
                ResourceManager.getInstance().getButtonPrevRegion().getTextureRegion(0),
                ResourceManager.getInstance().getButtonPrevRegion().getTextureRegion(1),
                ResourceManager.getInstance().getButtonPrevRegion().getTextureRegion(1),
                MainBoardScreen.getScm().getVertexBufferObjectManager(),
                new CustomButtonSprite.OnClickListener() {
                    @Override
                    public void onClick(CustomButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {
                        tutorialPages.get(currentPageIndex).detachPageAndShow(currentPageIndex - 1);
                        MainBoardScreen.getInstance().getGameSound().playTurnPageSound();
                        buttonNext.setEnabled(true);
                    }
                });
        buttonPrev.setPlaySound(false);
        if (currentPageIndex == 0) {
            buttonPrev.setEnabled(false);
        }
        if (currentPageIndex == tutorialPages.size() - 1) {
            buttonNext.setEnabled(false);
        }
        if (tutorialPages.size() == 1) {
            buttonNext.setVisible(false);
            buttonPrev.setVisible(false);
        }

        final Runnable closeAction = new Runnable() {
            @Override
            public void run() {
                MainBoardScreen.getInstance().setBackButtonAction(null);
                closeTutorial();
            }
        };

        MainBoardScreen.getInstance().setBackButtonAction(closeAction);
        buttonClose = new CustomButtonSprite(CAMERA_WIDTH / 2 + 150, CAMERA_HEIGHT / 2 + 340,
                ResourceManager.getInstance().getButtonCloseTextureRegion().getTextureRegion(0),
                ResourceManager.getInstance().getButtonCloseTextureRegion().getTextureRegion(1),
                MainBoardScreen.getScm().getVertexBufferObjectManager(),
                new CustomButtonSprite.OnClickListener() {
                    @Override
                    public void onClick(CustomButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {
                        MainBoardScreen.getInstanceEngine().runOnUpdateThread(closeAction);
                    }
                });

        MainBoardScreen.getScm().getTutorialLayer().attachChild(buttonClose);
        MainBoardScreen.getScm().getTutorialLayer().attachChild(buttonNext);
        MainBoardScreen.getScm().getTutorialLayer().attachChild(buttonPrev);

        tutorialPages.get(currentPageIndex).attachPage();
        setTutorialTouchAreas(true);

    }

    public void showTutorialForLevel(LevelDef currentLevel) {


        TutorialSection[] sectionsToShow = LevelDefinition.tutorialStructure.get(GameProfile.selectedLevelAreaIndex + "_" + GameProfile.selectedLevelIndex);
        if (sectionsToShow == null || sectionsToShow.length == 0) {
            return;
        }
        initPages(sectionsToShow);
        currentPageIndex = sectionsToShow.length - 1;
        showTutorial();
    }

    public void showTutorialForHelpButton() {
        GameSound.getCurrentInstance().playPopupSound();

        TutorialSection[] sectionsToShow = GameTutorial.TutorialSection.values();
        if (sectionsToShow == null || sectionsToShow.length == 0) {
            return;
        }

        initPages(sectionsToShow);
        currentPageIndex = 0;
        showTutorial();
    }


    private void initPages(TutorialSection[] sectionsToShow) {
        ResourceManager.getInstance().loadTutorialGfx(MainBoardScreen.getInstance());

        Sprite tutorialBg = new Sprite(0, 0, ResourceManager.getInstance().getTutorialBgRegion(), MainBoardScreen.getScm().getVertexBufferObjectManager());
        tutorialBg.setAnchorCenter(0, 0);
        MainBoardScreen.getScm().getTutorialLayer().attachChild(tutorialBg);


        tutorialPages.clear();
        for (int i = 0; i < sectionsToShow.length; i++) {
            final TutorialPage page = new TutorialPage();
            page.tutorialImage = getSpriteForSection(sectionsToShow[i]);
            page.tutorialImage.setAnchorCenter(0, 0);
            String pageCounterStr = (i + 1) + "/" + sectionsToShow.length;
            page.pageCounter = new Text(CAMERA_WIDTH / 2, CAMERA_HEIGHT / 2 + 320, ResourceManager.getInstance().getFontTrebuchetBoldTutorialPaging(),
                    pageCounterStr, 1000, new TextOptions(HorizontalAlign.CENTER), MainBoardScreen.getScm().getVertexBufferObjectManager());
            tutorialPages.add(page);
            MainBoardScreen.getScm().getTutorialLayer().attachChild(page.tutorialImage);
            MainBoardScreen.getScm().getTutorialLayer().attachChild(page.pageCounter);
            page.tutorialImage.setAlpha(0);
            page.pageCounter.setAlpha(0);

        }
    }

    private void closeTutorial() {
        setTutorialTouchAreas(false);
        MainBoardScreen.getScm().getTutorialLayer().detachChildren();
        MainBoardScreen.getScm().setBgTouchAreas(true, true);

    }

    class TutorialPage {
        private Entity tutorialImage;
        private Text pageCounter;

        void attachPage() {
            revealEntityAndChildren(0.3f, 0, 1, tutorialImage, null);
            revealEntityAndChildren(0.3f, 0, 1, pageCounter, null);
        }

        public void detachPageAndShow(int pageIndex) {
            if (pageIndex == tutorialPages.size() - 1) {
                buttonNext.setEnabled(false);
            }
            if (pageIndex == 0) {
                buttonPrev.setEnabled(false);
            }
            currentPageIndex = pageIndex;
            revealEntityAndChildren(0.3f, 1, 0, tutorialImage, null);
            revealEntityAndChildren(0.3f, 1, 0, pageCounter, null);

            tutorialPages.get(pageIndex).attachPage();
        }
    }

    private void setTutorialTouchAreas(boolean enabled) {
        if (enabled) {
            MainBoardScreen.getScm().getMainScene().registerTouchArea(buttonNext);
            MainBoardScreen.getScm().getMainScene().registerTouchArea(buttonPrev);
            MainBoardScreen.getScm().getMainScene().registerTouchArea(buttonClose);
        } else {
            MainBoardScreen.getScm().getMainScene().unregisterTouchArea(buttonNext);
            MainBoardScreen.getScm().getMainScene().unregisterTouchArea(buttonPrev);
            MainBoardScreen.getScm().getMainScene().unregisterTouchArea(buttonClose);
        }
    }

}
